import pandas as pd  # 加载 pandas 模块
import warnings
from matplotlib import pyplot as plt  # 加载绘图模块
# 集成方法分类器
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import RandomForestClassifier
# 高斯过程分类器
from sklearn.gaussian_process import GaussianProcessClassifier
# 广义线性分类器
from sklearn.linear_model import PassiveAggressiveClassifier
from sklearn.linear_model import RidgeClassifier
from sklearn.linear_model import SGDClassifier
# K近邻分类器
from sklearn.neighbors import KNeighborsClassifier
# 朴素贝叶斯分类器
from sklearn.naive_bayes import GaussianNB
# 神经网络分类器
from sklearn.neural_network import MLPClassifier
# 决策树分类器
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import ExtraTreeClassifier
# 支持向量机分类器
from sklearn.svm import SVC
from sklearn.svm import LinearSVC
from sklearn.model_selection import train_test_split  # 导入数据集切分模块

from sklearn.metrics import accuracy_score

from matplotlib.colors import ListedColormap  # 加载色彩模块
import numpy as np  # 导入数值计算模块
import os


# 读取 csv 文件, 并将第一行设为表头
data = pd.read_csv(
    "MLPClassifier_data.csv", header=0)


# 建立模型
models = [
    AdaBoostClassifier(),
    BaggingClassifier(),
    ExtraTreesClassifier(),
    GradientBoostingClassifier(),
    RandomForestClassifier(),
    GaussianProcessClassifier(),
    PassiveAggressiveClassifier(),
    RidgeClassifier(),
    SGDClassifier(),
    KNeighborsClassifier(),
    GaussianNB(),
    MLPClassifier(),
    DecisionTreeClassifier(),
    ExtraTreeClassifier(),
    SVC(),
    LinearSVC()
]

# 依次为模型命名
classifier_Names = ['AdaBoost', 'Bagging', 'ExtraTrees',
                    'GradientBoosting', 'RandomForest', 'GaussianProcess',
                    'PassiveAggressive', 'Ridge', 'SGD',
                    'KNeighbors', 'GaussianNB', 'MLP',
                    'DecisionTree', 'ExtraTree', 'SVC', 'LinearSVC']



feature = data[['X', 'Y']]  # 指定特征变量
target = data['CLASS']  # 指定标签变量
X_train, X_test, y_train, y_test = train_test_split(
    feature, target, test_size=.3)  # 切分数据集

# 绘制数据集
i = 1  # 为绘制子图设置的初始编号参数
cm = plt.cm.Reds  # 为绘制等高线选择的样式
cm_color = ListedColormap(['red', 'yellow'])  # 为绘制训练集和测试集选择的样式

# 栅格化
x_min, x_max = data['X'].min() - .5, data['X'].max() + .5
y_min, y_max = data['Y'].min() - .5, data['Y'].max() + .5

xx, yy = np.meshgrid(np.arange(x_min, x_max, .1),
                     np.arange(y_min, y_max, .1))

# 模型迭代
plt.figure(figsize=(20, 10))

for name, model in  zip(classifier_Names, models) :
    ax = plt.subplot(4, 4, i)  # 绘制 4x4 子图

    model.fit(X_train, y_train)  # 模型训练
    pre_labels = model.predict(X_test)  # 模型测试
    score = accuracy_score(y_test, pre_labels)  # 模型准确度

    # 根据类的不同选择决策边界计算方法
    if hasattr(model, "decision_function"):
        Z = model.decision_function(np.c_[xx.ravel(), yy.ravel()])
    else:
        Z = model.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 1]

    # 绘制决策边界等高线
    Z = Z.reshape(xx.shape)

    ax.contourf(xx, yy, Z, cmap=cm, alpha=.6)

    # 绘制训练集和测试集
    ax.scatter(X_train['X'], X_train['Y'], c=y_train, cmap=cm_color)
    ax.scatter(X_test['X'], X_test['Y'], c=y_test,
               cmap=cm_color, edgecolors='black')

    # 图形样式设定
    ax.set_xlim(xx.min(), xx.max())
    ax.set_ylim(yy.min(), yy.max())
    ax.set_xticks(())
    ax.set_yticks(())
    ax.set_title('%s | %.2f' % (name, score))
    i += 1

plt.tight_layout()
plt.show()